<?php
/**
 * Copyright (c) 2006, PORTALIER Julien
 *
 * Licensed under The LGPL License
 * Redistributions of files must retain the above copyright notice.
 *
 * @package      FeatherCMS
 * @subpackage   Tags
 * @copyright    Copyright (c) 2006, Julien PORTALIER
 * @link         http://julien.portalier.com
 * @license      http://www.opensource.org/licenses/lgpl-license.php The LGPL License
 */

abstract class TagModel extends Model
{
	public $recursiveProcess = Q_PROCESS_LIST;
	public $recursiveFields  = 'tag';
	public $tagName          = 'tag';
	
	protected $refererClass = null;
	protected $moduleClass  = null;
	
	function & getList()
	{
		$list = $this->listField($this->tagName);
		return $list;
	}
	
	function & cloud($module_id=null, $limit=null)
	{
		$referer   = (!is_null($this->refererClass)) ?
			$this->{$this->refererClass} : $this->{$this->moduleClass};
		
		if (!is_null($module_id))
			$this->conditions(array("{$this->name}.{$this->{$this->moduleClass}->foreignKey}" => $module_id));
		
		// prepares query
		$this->groupby("GROUP BY ".$this->db->field("{$this->name}.{$this->tagName}"));
		$this->order('tagcounter DESC');
		$fields = array(
			"{$this->name}.{$this->tagName}",
			'-! COUNT( '.$this->db->field("{$referer->name}.{$referer->primaryKey}").' ) AS '.$this->db->field('tagcounter')
		);
		
		// query
		$this->recursive = 0;
		$this->process   = Q_PROCESS_LITE;
		$_tags = $this->findAll(&$fields, $limit);
		
		// generates tag cloud ready array
		$tags = array();
		foreach ($_tags as $tag)
			$tags[$tag[$this->tagName]] = $tag['tagcounter'];
		ksort($tags);
		
		return $tags;
	}
	
	
	// internals
	
	function __save($type=null)
	{
		// referer (and module?)
		if (!is_null($this->refererClass))
		{
			$referer = $this->{$this->refererClass};
			$module  = $referer->{$this->moduleClass};
			
			if (!$module->id)
				$module->id = $this->data[$referer->name][$module->foreignKey];
			
			$fields  = array($module->foreignKey, $referer->foreignKey, $this->tagName);
		}
		else
		{
			$referer = $this->{$this->moduleClass};
			$fields  = array($referer->foreignKey, $this->tagName);
		}
		
		// tags
		$tags = $this->data[$this->name][$this->tagName];
		
		// removed all tags?
		if (empty($tags))
		{
			$this->conditions(array($referer->foreignKey => $referer->id));
			$this->__delete();
			return true;
		}
		elseif (is_string($tags))
			$tags = explode(',', $tags);
		
		$tags = array_unique($tags);
		foreach($tags as $i => $tag)
		{
			$tag = trim($tag);
			if (!empty($tag))
				$tags[$i] = $tag;
			else
				unset($tags[$i]);
		}
		
		// already sticked tags
		$this->conditions(array($referer->foreignKey => $referer->id));
		$_tags = $this->listField($this->tagName, -1);
		
		$new_tags = array_diff($tags, $_tags);
		$del_tags = array_diff($_tags, $tags);
		
		// deletes removed tags
		if (!empty($del_tags))
		{
			foreach ($del_tags as $i => $t)
				$del_tags[$i] = $this->db->value($t);
			
			$conditions = array($referer->foreignKey => $referer->id,
				$this->tagName => "-! IN (".implode(', ', $del_tags).")");
			
			if (!$this->__delete(&$conditions))
				return false;
		}
		
		// saves new tags
		if (!empty($new_tags))
		{
			$values = array();
			foreach($new_tags as $tag)
			{
				$entry = isset($module) ? array($module->id, $referer->id, $tag) : array($referer->id, $tag);
				array_push($values, $entry);
			}
			if (!$this->saveMany(&$fields, &$values))
				return false;
		}
		
		return $this->afterSave();
	}
	
	function rename()
	{
		$data =& $this->data[$this->name];
		
		if (!isset($data['old']) or !isset($data['new']))
			return false;
		
		if (isset($data['module_id']))
			$this->conditions(array($this->{$this->moduleClass}->foreignKey => $data['module_id']));
		
		$this->conditions(array($this->tagName => $data['old']));
		return $this->saveField($this->tagName, $data['new']);
	}		
}
?>